package com.alstudio.utils.android.imageProcess;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.ContentResolver;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.media.ExifInterface;
import android.net.Uri;

import com.alstudio.view.cropImage.Util;

/**
 * 图片处理工具类
 * 
 * @author alonso lee
 * 
 */
public class ALImageProcessUtils {

	private static Uri outputUri = null;

	/**
	 * 传入图片地址，根据图片的方向返回需要调整的角度
	 * 
	 * @param filePath
	 * @return
	 */
	private static int getRotate(String filePath) {
		int rotate = 0;

		if ((filePath == null) || (filePath.length() == 0)) {
			return 0;
		}

		try {
			ExifInterface exif;
			exif = new ExifInterface(filePath);
			int orientation = exif.getAttributeInt(
					ExifInterface.TAG_ORIENTATION,
					ExifInterface.ORIENTATION_NORMAL);
			switch (orientation) {
			case ExifInterface.ORIENTATION_ROTATE_270:
				rotate = 270;
				break;
			case ExifInterface.ORIENTATION_ROTATE_180:
				rotate = 180;
				break;
			case ExifInterface.ORIENTATION_ROTATE_90:
				rotate = 90;
				break;
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return rotate;
	}

	/**
	 * 获取指定参数的位图对象
	 * 
	 * @param ctx
	 * @param param
	 * @return
	 */
	private static Bitmap getBitmap(Context ctx, ALImageProcessParams param) {

		if (ctx == null) {
			throw new ALImageProcessException("上下文不能为空");
		}
		ContentResolver mContentResolver = ctx.getContentResolver();

		Uri uri = getImageUri(param.getImagePath());
		InputStream in = null;
		try {

			outputUri = getImageUri(param.getSavePath());

			final int IMAGE_MAX_SIZE = 1024;
			in = mContentResolver.openInputStream(uri);
			// Decode image size
			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inJustDecodeBounds = true;

			BitmapFactory.decodeStream(in, null, o);
			in.close();

			int scale = 1;
			if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
				scale = (int) Math.pow(
						2,
						(int) Math.round(Math.log(IMAGE_MAX_SIZE
								/ (double) Math.max(o.outHeight, o.outWidth))
								/ Math.log(0.5)));
			}

			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize = scale;
			in = mContentResolver.openInputStream(uri);
			Bitmap b = BitmapFactory.decodeStream(in, null, o2);

			// 检测是否需要旋转图片
			int degree = getRotate(param.getImagePath());
			if (degree > 0) {
				Matrix m = new Matrix();
				m.preRotate(degree);
				try {
					b = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
							b.getHeight(), m, true);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					b = null;
				}
			}

			in.close();

			return b;
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
		return null;
	}

	private static Uri getImageUri(String path) {
		return Uri.fromFile(new File(path));
	}

	/**
	 * 保存bitmap到指定路径
	 * 
	 * @param ctx
	 * @param image
	 * @return
	 */
	private static String saveOutput(Context ctx, Bitmap image) {
		String path = null;

		if (outputUri != null) {
			OutputStream outputStream = null;
			ContentResolver mContentResolver = ctx.getContentResolver();
			try {
				outputStream = mContentResolver.openOutputStream(outputUri);
				if (outputStream != null) {
					image.compress(Bitmap.CompressFormat.JPEG, 100,
							outputStream);
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			} finally {
				Util.closeSilently(outputStream);
				mContentResolver = null;
			}
			path = outputUri.getPath();
		}
		image.recycle();
		return path;
	}

	/**
	 * 此方法用于隐式地裁剪图片。裁剪并保存成功后，返回图片路径
	 * 
	 * @param act
	 * @param param
	 * @return
	 */
	public static String cropImage(Context ctx, ALImageProcessParams param) {
		Bitmap croppedImage = getBitmap(ctx, param);
		Bitmap old = croppedImage;

		croppedImage = Util.transform(new Matrix(), croppedImage,
				param.getRequestWidth(), param.getRequestHeight(), true);
		// 回收老图
		if (old != croppedImage) {
			old.recycle();
		}

		return saveOutput(ctx, croppedImage);
	}

	/**
	 * 此方法用于裁剪图片。裁剪成功后，返回Bitmap
	 * 
	 * @param bitmap
	 * @param width
	 * @param height
	 * @return
	 */
	public static Bitmap cropImage(Bitmap bitmap, int width, int height) {
		if (bitmap == null) {
			return null;
		}

		bitmap = Util.transform(new Matrix(), bitmap, width, height, true);
		return bitmap;
	}

	/**
	 * 将bitmap旋转指定度数
	 * 
	 * @param src
	 * @param degree
	 * @return
	 */
	public static Bitmap rotateImage(Bitmap src, float degree) {
		return Util.rotateImage(src, degree);
	}

	// Round Corner Bitmap
	public static Bitmap getRoundCornerBitmap(Bitmap bitmap, float roundPX) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();

		Bitmap bitmap2 = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap2);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, width, height);
		final RectF rectF = new RectF(rect);

		paint.setColor(color);
		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		canvas.drawRoundRect(rectF, roundPX, roundPX, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return bitmap2;
	}

	// Reflect Bitmap
	/**
	 * 创建倒影图片
	 * 
	 * @param bitmap
	 * @return
	 */
	public static Bitmap createReflectedBitmap(Bitmap bitmap) {
		final int reflectedGap = 4;
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();

		Matrix matrix = new Matrix();
		matrix.preScale(1, -1);

		Bitmap reflectedImage = Bitmap.createBitmap(bitmap, 0, height / 2,
				width, height / 2, matrix, false);
		Bitmap reflectedBitmap = Bitmap.createBitmap(width,
				(height + height / 2), Config.ARGB_8888);

		Canvas canvas = new Canvas(reflectedBitmap);
		canvas.drawBitmap(bitmap, 0, 0, null);
		Paint defaultPaint = new Paint();
		canvas.drawRect(0, height, width, height + reflectedGap, defaultPaint);
		canvas.drawBitmap(reflectedImage, 0, height + reflectedGap, null);

		Paint paint = new Paint();
		LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
				reflectedBitmap.getHeight() + reflectedGap, 0x70ffffff,
				0x00ffffff, TileMode.CLAMP);
		paint.setShader(shader);
		paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
		canvas.drawRect(0, height, width, reflectedBitmap.getHeight()
				+ reflectedGap, paint);

		return reflectedBitmap;
	}

}
